package com.classeven.downhill.engine;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.handler.IUpdateHandler;
import org.andengine.engine.handler.timer.ITimerCallback;
import org.andengine.engine.handler.timer.TimerHandler;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.modifier.MoveModifier;
import org.andengine.entity.modifier.RotationByModifier;
import org.andengine.entity.scene.IOnAreaTouchListener;
import org.andengine.entity.scene.IOnSceneTouchListener;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.sprite.Sprite;
import org.andengine.input.touch.detector.ClickDetector;
import org.andengine.input.touch.detector.ClickDetector.IClickDetectorListener;
import org.andengine.input.touch.detector.ScrollDetector;
import org.andengine.input.touch.detector.ScrollDetector.IScrollDetectorListener;
import org.andengine.ui.activity.SimpleBaseGameActivity;

import android.content.Intent;
import android.os.Handler;
import android.view.KeyEvent;
import android.widget.Toast;

import com.classeven.downhill.define.iGameDefines;
import com.classeven.downhill.element.AAnimatedSprite;
import com.classeven.downhill.element.ABackground;
import com.classeven.downhill.element.AFont;
import com.classeven.downhill.element.AHud;
import com.classeven.downhill.element.ARectangle;
import com.classeven.downhill.element.AScene;
import com.classeven.downhill.element.ASprite;
import com.classeven.downhill.element.AStrokeText;
import com.classeven.downhill.element.AText;



public abstract class GameEngine extends SimpleBaseGameActivity implements IUpdateHandler, IOnSceneTouchListener,
IClickDetectorListener, IOnAreaTouchListener, IScrollDetectorListener
{
	public static float SCREEN_WIDTH, SCREEN_HEIGHT, CAMERA_WIDTH, CAMERA_HEIGHT;
	public static ScreenOrientation ORIENTATION;

	protected Camera camera;
	public Scene mScene =  new Scene();
	protected ClickDetector mClickDetector = new ClickDetector(this);
	protected ScrollDetector mScrollDetector = new ScrollDetector(this);
	int gameUpdateStep;

	public int gameCurrentState, gameNextState;
	public int messageCurrentState, messageNextState;

	private long waitTime, waitTimeElapsed, waitTimeRemaining;
	
	String TAG_UPDATE = "AGD_UPDATE";
	String TAG_STATE = "AGD_STATE";
	
	public AFont gameFont[] = new AFont[iGameDefines.FONT_COUNT];
	
	public final Handler handler = new Handler();
	
	AScene scene;
	
	public static SimpleBaseGameActivity context;



	public EngineOptions onCreateEngineOptions() 
	{
		context = this;
		GameInit();
		camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		EngineOptions engineOptions = new EngineOptions(true, ORIENTATION, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
		
		engineOptions.getAudioOptions().setNeedsMusic(true).setNeedsSound(true);
		return engineOptions;
		
	}


	protected void onCreateResources() 
	{
		mEngine.registerUpdateHandler(this);
		
	}

	@Override
	protected Scene onCreateScene() 
	{
		LoadAllFont();
		return mScene;
	}

	public void onUpdate(float pSecondsElapsed) 
	{
//		if(iConfiguration.use_debug_gameUpdate)
//		{
//			Utils.TRACE("gameUpdateStep = "+gameUpdateStep);
//		}
	
		GameUpdate();
	}

	
	public void reset() 
	{		
	}
	
	@Override
	public synchronized void onPauseGame() 
	{
		super.onPauseGame();
	}

	@Override
	public synchronized void onResumeGame() 
	{
		super.onResumeGame();
		waitTime = System.currentTimeMillis() + waitTimeRemaining;
	}
	
	public void WaitTimeCapture() 
	{
		waitTime = System.currentTimeMillis();
	}

	public boolean IsTimePassed(long ms) 
	{
		waitTimeElapsed = System.currentTimeMillis() - waitTime;
		waitTimeRemaining = ms - waitTimeElapsed;
		if (waitTime + ms <= System.currentTimeMillis()) {
			waitTimeElapsed = 0;
			waitTimeRemaining = 0;

			return true;
		}
		return false;
	}
	
	public boolean IsCurrentTimeShorterThanCaptured(long ms)
	{
		waitTimeElapsed = System.currentTimeMillis() - waitTime;
		waitTimeRemaining = ms - waitTimeElapsed;
		if (waitTime + ms > System.currentTimeMillis()) {
			waitTimeElapsed = 0;
			waitTimeRemaining = 0;

			return true;
		}
		return false;
	}
	
	public void SetNextMessageState(int message) 
	{
		messageNextState = message;
	}

	public void SetNextGameState(int message) 
	{
		gameNextState = message;
	}

	public int NextMessageState() 
	{
		int next = messageCurrentState + 1;
		if (next > iGameDefines.MESSAGE_STATE_EXIT) 
		{
			return iGameDefines.MESSAGE_STATE_INIT;
		}
		return next;
	}

	public int NextGameState() 
	{
		return gameCurrentState + 1;
	}
	
	public abstract void GameInit();
	public abstract void GameUpdate();
	
	public void SetGameScene(AScene scene)
	{
		this.scene = scene;
		mEngine.setScene(scene.theScene());
	}
	
	public AScene getGameScene()
	{
		return scene;
	}

	public void HudAttach(AHud hud, ASprite sprite)
	{
		hud.theHud().attachChild(sprite.theSprite());
	}
	
	public void attachParent(ASprite sprParent, ASprite sprChild)
	{
		sprParent.theSprite().attachChild(sprChild.theSprite());
	}
	
	public void attachParent(ASprite sprParent, AText txt)
	{
		sprParent.theSprite().attachChild(txt.theText());
	}
	
	public void SceneAttach(AScene scene, ASprite sprite)
	{
		scene.theScene().attachChild(sprite.theSprite());
	}

	public void SceneAttach(AScene scene, AAnimatedSprite sprite)
	{
		scene.theScene().attachChild(sprite.theSprite());
	}
	
	public void SceneAttach(AScene scene, ABackground sprite)
	{
		scene.theScene().attachChild(sprite.theSprite());
	}
	
	
	public void SceneAttach(AScene scene, AText text)
	{
		scene.theScene().attachChild(text.theText());
	}
	
	public void SceneAttach(AScene scene, AStrokeText text)
	{
		scene.theScene().attachChild(text.theText());
	}
	
	public void SceneAttach(AScene scene, ARectangle rect)
	{
		scene.theScene().attachChild(rect.theRect());
	}
	

	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) 
	{
		return false;
	}
	
	void LoadAllFont()
	{
		for(int i = 0; i < gameFont.length; i++)
		{
			gameFont[i] = new AFont(this, i);
		}
	}
	
	public void exit()
	{
		finish();
	}
	
	public void moveObj(final float pDuration, final float pFromX,
			final float pToX, final float pFromY, final float pToY,
			final Sprite sprite) {
		// TODO Auto-generated method stub
		TimerHandler handler = new TimerHandler(0.2f, new ITimerCallback() {

			public void onTimePassed(TimerHandler pTimerHandler) {
				// TODO Auto-generated method stub

				MoveModifier modifier = new MoveModifier(pDuration, pFromX,
						pToX, pFromY, pToY);
				sprite.registerEntityModifier(modifier);

			}
		});

		mEngine.registerUpdateHandler(handler);
	}
	
	public void rotateObj(final ASprite spr, final int plusMin)
	{
		TimerHandler handler = new TimerHandler(0.1f, new ITimerCallback() {
			
			public void onTimePassed(TimerHandler pTimerHandler) {
				// TODO Auto-generated method stub
				spr.theSprite().registerEntityModifier(new RotationByModifier(0.4f, plusMin * 180));
			}
		});
		
		mEngine.registerUpdateHandler(handler);
	}
	
	public void makeToast(String str, int duration)
	{
		Toast.makeText(this,str , duration).show();
	}
	
//	protected void onActivityResult(int requestCode, int resultCode, Intent data)
//	{
//		server_Client.onActivityResult(requestCode, resultCode, data);
//		super.onActivityResult(requestCode, resultCode, data);
//	}
}
